package models

import (
	"fmt"
	"gorm.io/gorm"
	"time"
	"user_srv/basic/config"
)

// Withdrawal 提现申请表
type Withdrawal struct {
	ID            uint64         `gorm:"column:id;type:bigint UNSIGNED;primaryKey;not null;autoIncrement;" json:"id"`
	UserID        uint64         `gorm:"column:user_id;type:bigint UNSIGNED;not null;index;comment:用户ID" json:"user_id"`
	WithdrawalNo  string         `gorm:"column:withdrawal_no;type:varchar(32);uniqueIndex;not null;comment:提现单号" json:"withdrawal_no"`
	Amount        float64        `gorm:"column:amount;type:decimal(12,2);not null;comment:提现金额" json:"amount"`
	AccountType   int8           `gorm:"column:account_type;type:tinyint(1);not null;comment:收款账户类型(1-银行卡,2-支付宝,3-微信)" json:"account_type"`
	AccountNumber string         `gorm:"column:account_number;type:varchar(100);not null;comment:收款账号" json:"account_number"`
	AccountName   string         `gorm:"column:account_name;type:varchar(50);not null;comment:收款账户姓名" json:"account_name"`
	BankName      string         `gorm:"column:bank_name;type:varchar(50);comment:开户银行名称" json:"bank_name"`
	Status        int8           `gorm:"column:status;type:tinyint(1);default:0;index;comment:状态(0-待审核,1-审核通过,2-审核拒绝,3-提现中,4-提现成功,5-提现失败)" json:"status"`
	RejectReason  string         `gorm:"column:reject_reason;type:varchar(500);comment:拒绝原因" json:"reject_reason"`
	AuditorID     uint64         `gorm:"column:auditor_id;type:bigint UNSIGNED;comment:审核人ID" json:"auditor_id"`
	AuditTime     *time.Time     `gorm:"column:audit_time;type:timestamp;comment:审核时间" json:"audit_time"`
	Remark        string         `gorm:"column:remark;type:text;comment:备注" json:"remark"`
	CreatedAt     time.Time      `gorm:"column:created_at;type:datetime(3);not null;default:CURRENT_TIMESTAMP(3);" json:"created_at"`
	UpdatedAt     time.Time      `gorm:"column:updated_at;type:datetime(3);not null;default:CURRENT_TIMESTAMP(3);" json:"updated_at"`
	DeletedAt     gorm.DeletedAt `gorm:"column:deleted_at;type:datetime(3);" json:"deleted_at"`
}

// Create 创建提现申请
func (w *Withdrawal) Create() error {
	return config.DB.Create(&w).Error
}

// update 更新提现申请
func (w *Withdrawal) Update() error {
	return config.DB.Save(&w).Error
}

// GetByID 根据ID查询
func (w *Withdrawal) GetByID() error {
	return config.DB.Where("id = ?", w.ID).First(&w).Error
}

// GetByWithdrawal 根据提现单号查询
func (w *Withdrawal) GetByWithdrawalNo() error {
	return config.DB.Where("withdrawal_no = ?", w.WithdrawalNo).First(&w).Error
}

// GetByUserID 获取用户的提现记录列表
func (w *Withdrawal) GetByUserID(page, pageSize int) (list []*Withdrawal, total int64, err error) {
	query := config.DB.Where("user_id = ?", w.UserID)
	err = query.Model(&Withdrawal{}).Count(&total).Error
	if err != nil {
		return nil, 0, err
	}
	err = query.Order("created_at DESC").Scopes(Paginate(page, pageSize)).Find(&list).Error
	return list, total, err
}

// updateStatus 更新状态
func (w *Withdrawal) UpdateStatus(status int8, auditorID uint64, reason string) error {
	now := time.Now()
	updates := map[string]interface{}{
		"status": status,
	}

	if status == 2 || status == 1 {
		updates["auditor_id"] = auditorID
		updates["audit_time"] = now
		if reason != "" {
			updates["reject_reason"] = reason
		}
	}
	return config.DB.Model(&w).Where("id = ?", w.ID).Updates(updates).Error
}

// GetAll 获取所有提现记录（用于后台管理）
func (w *Withdrawal) GetAll(page, pageSize int) (list []*Withdrawal, total int64, err error) {
	query := config.DB.Model(&Withdrawal{})
	err = query.Count(&total).Error
	if err != nil {
		return nil, 0, err
	}
	err = query.Order("created_at DESC").Scopes(Paginate(page, pageSize)).Find(&list).Error
	return list, total, err
}

// SumAmountGroup 按区间/天/月/年聚合统计金额
// start: 开始时间 格式: 2024-01-01 或 2024-01-01 00:00:00
// end: 结束时间 格式: 2024-01-31 或 2024-01-31 23:59:59
// groupType: 分组类型 1=按日 2=按月 3=按年
func SumAmountGroup(start, end string, groupType int) (xAxis []string, yAxis []float64, err error) {
	// 参数验证
	if groupType < 1 || groupType > 3 {
		return nil, nil, fmt.Errorf("分组类型无效，仅支持1(按日)/2(按月)/3(按年)")
	}

	db := config.DB.Model(&Withdrawal{}).Where("status = ?", 4) // 仅统计成功提现

	// 时间范围过滤
	if start != "" && end != "" {
		// 确保时间格式正确，如果只传日期则补全时间
		startTime := start
		endTime := end
		if len(start) == 10 {
			startTime = start + " 00:00:00"
		}
		if len(end) == 10 {
			endTime = end + " 23:59:59"
		}
		db = db.Where("created_at >= ? AND created_at <= ?", startTime, endTime)
	}

	// 根据分组类型确定日期格式
	var groupFormat string
	switch groupType {
	case 1:
		groupFormat = "%Y-%m-%d" // 按日
	case 2:
		groupFormat = "%Y-%m" // 按月
	case 3:
		groupFormat = "%Y" // 按年
	default:
		groupFormat = "%Y-%m-%d"
	}

	// 使用参数化查询避免SQL注入
	var rows []struct {
		Period string  `gorm:"column:period"`
		Amount float64 `gorm:"column:amount"`
	}

	err = db.Select("DATE_FORMAT(created_at, ?) as period, COALESCE(SUM(amount), 0) as amount", groupFormat).
		Group("period").
		Order("period ASC").
		Scan(&rows).Error

	if err != nil {
		return nil, nil, fmt.Errorf("查询提现统计失败: %w", err)
	}

	// 构建返回数据
	xAxis = make([]string, 0, len(rows))
	yAxis = make([]float64, 0, len(rows))

	for _, r := range rows {
		if r.Period != "" {
			xAxis = append(xAxis, r.Period)
			yAxis = append(yAxis, r.Amount)
		}
	}

	return xAxis, yAxis, nil
}
